<template>
  <!-- 筛选器控件 -->
  <div
    class="comp-filter-form"
    :class="{
      'hide-label': !config.chartOptions.showLabel,
    }"
  >
    <div v-if="usefulColumns.length === 0" class="no-data">
      <div class="content">
        <img
          class="no-data-img"
          :src="getChartImage()"
          alt="filter form"
          draggable="false"
        />
        <span class="no-data-text">暂无数据</span>
      </div>
    </div>
    <a-form
      v-else-if="inited"
      size="small"
      layout="vertical"
      class="filter-form"
    >
      <a-form-item
        v-for="(item, i) in usefulColumns"
        :key="i"
        class="filter-form-item"
        :class="{
          'first-fix': !item.isNumber && i === 0,
          numberic: item.isNumber,
        }"
        :name="item.value"
        :label="
          config.chartOptions.showLabel
            ? item.isGraphColumn
              ? item.value.split('[')[0]
              : item.value
            : ''
        "
      >
        <range-number
          v-if="item.isNumber"
          class="numberic"
          :title="
            IsTaskFilter && !columns.includes(item.label)
              ? '列不存在或者已被删除'
              : ''
          "
          :config="{
            isGraphColumn: item.isGraphColumn,
            projectId: item.projectId,
            min: item.min,
            max: item.max,
            startNodeType: starNodeType,
            tableName: item.tableName,
            colName: item.value,
            type: item.type,
            dataId: nodeIdMap[item.dataId]
              ? nodeIdMap[item.dataId]
              : item.dataId,
          }"
          :value="formDataInner[item.value] || [0, 100]"
          :step="item.step || 1"
          :invalid="IsTaskFilter && !columns.includes(item.label)"
          :parent="self"
          :disabled="disabled"
          @change="
            (value) => {
              onFieldChange(value, item)
            }
          "
        />
        <remote-selector
          v-else
          :title="
            IsTaskFilter && !columns.includes(item.label)
              ? '列不存在或者已被删除'
              : ''
          "
          :config="{
            tableName: item.tableName,
            colName: item.value,
            type: item.type,
            startNodeType: starNodeType,
            dataId: nodeIdMap[item.dataId]
              ? nodeIdMap[item.dataId]
              : item.dataId,
            projectId: item.projectId,
            isGraphColumn: item.isGraphColumn,
          }"
          :parent="self"
          :value="formDataInner[item.value] || []"
          :disabled="disabled"
          :invalid="IsTaskFilter && !columns.includes(item.label)"
          @change="
            (value) => {
              onFieldChange(value, item)
            }
          "
        />
      </a-form-item>
    </a-form>
  </div>
</template>
<script lang="ts">
// import { getNodeTableById } from '@/api/data-list'
// import visGraphService from '@/store/modules/vis-graph-service'
import { tcolumnQueryDetail } from '@/api/widget'
import { cloneDeep, debounce, isEqual } from 'lodash'
import { Component, Vue, Prop, Watch } from 'vue-property-decorator'
import RangeNumber from './range-number.vue'
import RemoteSelector from './remote-selector.vue'
import VisualizationStore from '@/store/modules/visualization'

export interface IFilterChartOptions {
  filterColumns: any[]
  [key: string]: any
}

export interface IFilterFormConfig {
  chartOptions: IFilterChartOptions
}

/** 筛选表单 */
@Component({
  components: {
    RangeNumber,
    RemoteSelector,
  },
})
export default class FilterForm extends Vue {
  @Prop() config!: IFilterFormConfig

  @Prop() disabled!: boolean

  @Prop() dataset!: any[]

  @Prop() pipelineId!: string | number

  @Prop({
    type: Object,
    default() {
      return {}
    },
  })
  nodeIdMap!: any

  form: any

  inited: boolean = false

  get publishNo() {
    return VisualizationStore.publishNo.length > 0
      ? VisualizationStore.publishNo
      : undefined
  }

  /** 列信息缓存 */
  private columnInfoCache: any = {}

  get taskTableInfo() {
    return this.dataset
      ? ((this.dataset[0]?.pipeline || []) as any[]).map((item) => {
          return {
            id: item.id,
            tableName: item.tableName,
          }
        })
      : []
  }

  /** 有效筛选字段 */
  get usefulColumns() {
    return (
      this.config?.chartOptions?.filterColumns?.filter(
        (item: any) => ![null, undefined, ''].includes(item.value)
      ) || []
    )
  }

  formDataInner: any = {}

  get starNodeType() {
    return this.config?.chartOptions.starNodeType
  }

  get formData() {
    return this.config?.chartOptions.queryData || {}
  }

  get projectId() {
    return (this.$route.params as any).id
  }

  get self() {
    return this
  }

  /** 是否为pipeline节点筛选 */
  get IsTaskFilter() {
    return this.config?.chartOptions.starNodeType === 'task'
  }

  /** 获取缓存字段 */
  getCacheKey(item: any) {
    return `${item.tableName}_${item.value}_${item.type}_${item.dataId}`
  }

  private get themeSetting() {
    return VisualizationStore.layoutData.themeSetting
  }

  private getChartImage() {
    return ['dark', 'nebula'].includes(this.themeSetting.theme)
      ? '/icon/components/filter-dark.png'
      : '/icon/components/filter.png'
  }

  /** 获取列信息缓存 */
  public getColumnInfoByCache(key: string) {
    return this.columnInfoCache[key] || null
  }

  /** 设置列信息缓存 */
  public setColumnInfo(key: string, value: any) {
    this.columnInfoCache[key] = value
  }

  public columns: any[] = []

  @Watch('config', { immediate: true })
  initFormData(newValue: IFilterFormConfig) {
    return this.buildFormData(newValue)
  }

  private checkEq(
    changedValues: { [key: string]: any },
    formData: { [key: string]: any }
  ) {
    return Object.keys(changedValues).reduce((rec: boolean, key: string) => {
      if (rec) {
        rec = isEqual(changedValues[key], formData[key])
      }
      return rec
    }, true)
  }

  created() {
    // const that = this
    // this.buildFormData(this.config)
    this.form = this.$form.createForm(this, {
      name: `filterForm_${Math.random().toString().slice(2, 11)}`,
      // @ts-ignore
      // onValuesChange: (formEle, changedValues, allValues) => {
      //   if (!that.checkEq(changedValues, that.formData)) {
      //     this.onFormValueChange(allValues)
      //   }
      // },
    })
  }

  /** 初始化表单 */
  async buildFormData(newValue: any) {
    const { publishNo } = this
    // 数据id默认从 dataId 拿，之前的旧数据无dataId，再从startNode 拿
    const startNode = (newValue?.chartOptions?.dataId ||
      newValue?.chartOptions?.startNode) as string | number
    if (
      startNode &&
      newValue?.chartOptions.starNodeType === 'task' &&
      this.pipelineId &&
      this.taskTableInfo[0]
    ) {
      const startNodeUsed = this.nodeIdMap[startNode]
        ? this.nodeIdMap[startNode]
        : startNode
      const nodeInfo = this.taskTableInfo.find((n) => n.id === startNodeUsed)
      const dataSend = {
        data: {
          curPage: 1,
          filter: [],
          name: '_record_id_',
          pageSize: 1,
          table: nodeInfo?.tableName,
          taskId: nodeInfo?.id,
          publishNo,
        },
      }

      const result = await tcolumnQueryDetail(dataSend)
      if (result.data.code === 100) {
        const columns = (result.data.result?.head || []).map((c: any) => c.name)
        this.columns = columns
      }

      // // 考虑到多人操作pipeline的情况，这里去除了缓存
      // // const cacheKey = `_${startNode}`
      // // const cacheData = await visGraphService.getCachePipelineNode(cacheKey)
      // // if(cacheData) {
      // //   newValue.chartOptions.filterColumns =  newValue.chartOptions?.filterColumns.map((col: any) => {
      // //       return {
      // //         ...col,
      // //         tableName: cacheData.tableName
      // //       }
      // //     })
      // //   this.columns = cacheData.columns || []
      // // } else {
      // const result = await getNodeTableById({ data: { id: startNode } })
      // const tableName =
      //   (result.data?.result?.data?.output || [])[0]?.tableName || ''
      // const columns =
      //   (result.data?.result?.data?.output || [])[0]?.tableCols || []
      // if (result.data.code === 100 && tableName) {
      //   newValue.chartOptions.filterColumns = newValue.chartOptions?.filterColumns.map(
      //     (col: any) => {
      //       return {
      //         ...col,
      //         tableName,
      //       }
      //     }
      //   )

      //   // visGraphService.savePipeNodeInfo({
      //   //   id: cacheKey,
      //   //   data: {
      //   //     columns,
      //   //     tableName
      //   //   }
      //   // })
      //   this.columns = columns
      //   // }
      // }
    }
    newValue.chartOptions.queryData =
      newValue.chartOptions.queryData || ({} as any)
    ;(newValue.chartOptions.filterColumns || []).forEach((col: any) => {
      if (
        ![null, undefined, ''].includes(col.value) &&
        newValue.chartOptions.queryData[col.value] === undefined
      ) {
        newValue.chartOptions.queryData[col.value] =
          col.type === 'number' ? [col.min || 0, col.max || 100] : []
      }
    })
    this.formDataInner = cloneDeep(newValue.chartOptions.queryData || {})
    setTimeout(() => {
      this.inited = true
    }, 10)
    return newValue
  }

  /** 用于外部调用 */
  getResetData() {
    const dataSet = cloneDeep(this.config.chartOptions)
    dataSet.queryData = dataSet.queryData || {}
    this.usefulColumns.forEach((field) => {
      if (field.isNumber) {
        const cacheData = field.isGraphColumn
          ? field
          : this.getColumnInfoByCache(this.getCacheKey(field))
        dataSet.queryData[field.value] =
          cacheData.min !== undefined && cacheData.max !== undefined
            ? [cacheData.min, cacheData.max]
            : []
      } else {
        dataSet.queryData[field.value] = []
      }
    })
    return dataSet.queryData
  }

  /** 字段变更 */
  onFieldChange(value: any, field: any) {
    if (field.isNumber && [null, undefined, ''].includes(field.step)) {
      field.step = 1
    }
    this.formDataInner[field.value] = value
    this.config.chartOptions.queryData =
      this.config.chartOptions.queryData || {}
    this.$set(this.config.chartOptions.queryData, field.value, value)
    this.dataChange()
  }

  dataChange = debounce(() => {
    this.$emit('change', this.config)
  }, 100)

  /** 数据变更回调 暂时不使用 */
  // onFormValueChange(allValues: any) {
  //   console.log('allValues', allValues)
  // }
}
</script>
<style lang="less" scoped>
.comp-filter-form {
  box-sizing: border-box;
  height: 100%;
  overflow-y: scroll;
  padding: 20px;
  width: 100%;

  &.hide-label {
    padding-bottom: 0;
    padding-top: 2px;
  }

  &::-webkit-scrollbar {
    width: 6px;
  }

  &::-webkit-scrollbar-thumb {
    background: rgba(144, 147, 153, 0.5);
    border-radius: 6px;
  }

  &::-webkit-scrollbar-track {
    background: transparent;
    border-radius: 5px;
  }

  .filter-form-item {
    height: auto;
    margin-bottom: 0;
    min-width: 306px;
    width: 100%;

    &.first-fix {
      padding-top: 8px;
    }

    /deep/ .ant-form-item-label {
      color: #373b52;
      font-size: 14px;
      height: 20px;
      line-height: 20px;
      margin-bottom: 4px;
      margin-top: 4px;
    }

    &.numberic {
      /deep/ .ant-form-item-label {
        margin-bottom: 0;
      }
    }

    /deep/ .ant-slider {
      margin-bottom: 9px;
      margin-top: 7px;
    }
  }

  .no-data {
    display: block;
    height: 100%;
    position: relative;
    width: 100%;

    .content {
      display: block;
      height: auto;
      left: 50%;
      position: absolute;
      text-align: center;
      top: 50%;
      transform: translate(-50%, -50%);
      width: 208px;
    }

    .no-data-img {
      display: block;
      height: auto;
      width: 208px;
    }

    .no-data-text {
      color: #d9d9d9;
      display: block;
      text-align: center;
      width: 100%;
    }
  }

  /deep/ .ant-form-item-label > label {
    color: var(--controller-label);
  }

  /deep/ .ant-checkbox,
  /deep/ .ant-checkbox-wrapper {
    color: var(--controller-label);
  }

  /deep/ .ant-input,
  /deep/ .ant-select-selection,
  /deep/ .ant-input-number,
  /deep/ .ant-input-number-handler-wrap {
    background-color: transparent;
    border: 1px solid var(--controller-input-border);
    color: var(--controller-label);

    &:hover,
    &:focus {
      border: 1px solid #6973ff;
      border-radius: 2px;
      outline: none;
    }
  }

  /deep/ .ant-input-number-handler-up-inner,
  /deep/ .ant-input-number-handler-down-inner {
    color: var(--controller-innput-arrow);
  }

  /deep/ .ant-slider-rail {
    background-color: var(--controller-slider-rail);
  }

  /deep/ .ant-slider-track {
    background-color: #6973ff;
  }

  /deep/ .ant-select-selection__choice {
    background: var(--component-bg-color);
    border: 1px solid var(--controller-input-border);
    color: var(--controller-label);
  }

  /deep/ .ant-select-selection__clear {
    background: var(--component-bg-color);
    color: var(--controller-label);
  }

  /deep/ .ant-select-selection__choice__remove {
    color: var(--controller-label);
  }
}

.comp-filter-form.remove-scroll {
  overflow: hidden;
}
</style>
